package cn.shanguoyu.netty.test.day01;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author：sgy
 * @date: 2023-06-20
 */
@Slf4j
public class NettyServer {
    public static void main(String[] args) throws Exception {
        // 稍微总结一下吧：创建了内部所有被管理的EventLoop，NioEventLoop内部创建了Selector，初始化了NioEventLoop的任务队列啥的，没有启动内部的线程
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .localAddress(new InetSocketAddress(8080))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 只关注读写空闲
                        ch.pipeline().addLast(new IdleStateHandler(0, 0, 5, TimeUnit.SECONDS));
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                            @Override
                            public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                                // 是空闲事件
                                if (evt instanceof IdleStateEvent) {
                                    IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
                                    // 是读空闲事件
                                    if (idleStateEvent.state() == IdleState.READER_IDLE) {
                                        log.info("读空闲...[{}]");
                                    }
                                    // 是写空闲事件
                                    else if (idleStateEvent.state() == IdleState.WRITER_IDLE) {
                                        log.info("写空闲...[{}]");

                                    }
                                    // 是读写空闲事件
                                    else if (idleStateEvent.state() == IdleState.ALL_IDLE) {
                                        log.info("读写空闲...[{}]");
                                        ctx.channel().close();
                                    }
                                }
                            }
                        });
                    }
                });
        ChannelFuture sync = serverBootstrap.bind().sync();
        sync.channel().closeFuture().sync();
    }
}
